<script>
import { apiStudentSaveWork, getPaperDetail } from '@/api/experiment'
import * as echarts from 'echarts'
import { Loading } from 'element-ui'

let socket
let handlerInterval = 0

let socketChannelData = {}
const chartInstanceMap = new WeakMap()
const measureInstanceMap = new WeakMap()
const chartInstanceKeys = []
const currentSocketData = {}
const currentSocketDataList = []
const resizeObserver = new ResizeObserver((entries, observer) => {
  for (const entry of entries) {
    if (chartInstanceMap.has(entry.target)) {
      chartInstanceMap.get(entry.target).resize()
    }
    if (measureInstanceMap.has(entry.target)) {
      measureInstanceMap.get(entry.target).resize()
    }
  }
})

export default {
  props: {
    testId: {
      type: [String, Number],
      default: '',
    },
  },
  data() {
    return {
      currentHtml: '',
      tabs: [],
      currentTab: 0,
      deviceList: [],
      calculateList: [],
      deviceValueList: [],
      calculateValueList: [],
      channelBtnType: {},
    }
  },
  mounted() {
    this.makeStorageData().then(() => {
      this.currentHtml = sessionStorage.getItem('currentHtml')
      let loadingInstance = Loading.service({ fullscreen: true })
      setTimeout(() => {
        this.makePreviewHtml()
        loadingInstance.close()
      }, 1500)
    })
  },
  beforeDestroy() {
    document.querySelectorAll('span.wordDescription').forEach(item => {
      item.removeEventListener('click', () => {})
    })
    if (handlerInterval) {
      clearInterval(handlerInterval)
    }
    if (socket) {
      socket.stop()
    }
  },
  methods: {
    makeStorageData() {
      return new Promise((resolve, reject) => {
        getPaperDetail(this.$props.testId).then(res => {
          const paperContent = res.data['testPaperContent']
          const json = JSON.parse(paperContent)
          if (json['storage']) {
            for (const key in json['storage']['local']) {
              localStorage.setItem(key, json['storage']['local'][key])
            }
            for (const key in json['storage']['session']) {
              sessionStorage.setItem(key, json['storage']['session'][key])
            }
          }
          resolve()
        }).catch(reject)
      })
    },
    handleChangeTab(e) {
      const allWrapperList = document.querySelectorAll('div.group-wrapper')
      allWrapperList.forEach((itemWrapper, index) => {
        this.currentTab = e
        if (e === index) {
          itemWrapper.style.display = 'block'
        } else {
          itemWrapper.style.display = 'none'
        }
      })
    },
    addNewRow(table) {
      if (!table) return

      const ths = table.querySelectorAll('thead tr th')
      const tbody = table.querySelector('tbody')
      if (!ths.length || !tbody) return

      const newTr = document.createElement('tr')

      ths.forEach(th => {
        const td = document.createElement('td')
        try {
          // 直接解析原生属性值（浏览器已自动转换 &quot; 为正常引号）
          const dataBind = JSON.parse(th.dataset.bind || '{}')

          // 获取数据源
          const [sourceList, key] = dataBind.type === 'calculate'
            ? [this.calculateValueList, dataBind.alias]
            : [this.deviceValueList, dataBind.alias]

          // 填充数据（取最新值）
          if (sourceList?.length > 0) {
            td.textContent = sourceList[sourceList.length - 1][key] || ''
          }
        } catch (e) {
          console.warn(this.$locale('experiment.components.GeWuTest.Analysis failed'), th, e)
        }
        newTr.appendChild(td)
      })

      tbody.appendChild(newTr)
    },
    calculateUrms(U) {
      const M = U.length
      let sum = 0
      for (let s = 0; s < M; s++) {
        sum += Math.pow(U[s], 2)
      }
      return Math.sqrt(sum / M)
    },
    initSocket(e) {
      currentSocketDataList.splice(0, currentSocketDataList.length)
      Object.keys(currentSocketData).forEach(key => delete currentSocketData[key])
      socket = new WebSocket('ws://localhost:8080')
      socket.onopen = () => {
        socket.onmessage = (msg) => {
          const result = JSON.parse(msg.data)
          if (!result['channelData']) {
            result['channelData'] = {}
          }
          for (const waveformDataKey in result['waveformData']) {
            const tempValue = this.calculateUrms(result['waveformData'][waveformDataKey])
            result['channelData'][waveformDataKey] = tempValue
          }
          for (const key in result['channelData']) {
            currentSocketData[key] = result['channelData'][key]
          }
          for (const item of e.childNodes) {
            if (!item.dataset['bind']) break
            const bind = JSON.parse(item.dataset['bind'])
            if (bind['type'] === 'channelData1') {
              const alias = bind['channelData'][0]['channelAlias']
              const value = result['channelData'][alias]
              item.querySelector('.multimeter-value').innerHTML = value.toFixed(3)
            } else if (bind['type'] === 'channelData2') {
              const chartDom = item.querySelector('.chart-div')
              const yMax1 = parseInt(item.dataset['yMax1'])
              const yMax2 = parseInt(item.dataset['yMax2'])
              const $yMax1 = -1 * yMax1
              const $yMax2 = -1 * yMax2
              let values = []
              let series = []
              let i = 0
              for (const channelData of bind['channelData']) {
                i++
                const alias = channelData['channelAlias']
                if (alias) {
                  const value = result['channelData'][alias]
                  values.push(value)
                  series.push({
                    name: this.$locale('experiment.components.GeWuTest.thoroughfare') + i.toString(),
                    type: 'line',
                    data: result['waveformData'][alias],
                    showSymbol: false,
                    yAxisIndex: i - 1,
                  })
                }
              }
              if (chartInstanceMap.has(chartDom)) {
                chartInstanceMap.get(chartDom).setOption({
                  series,
                  yAxis: [
                    {
                      type: 'value',
                      name: this.$locale('experiment.components.GeWuTest.thoroughfare1'),
                      axisLine: { lineStyle: { color: '#333' } },
                      max: yMax1,
                      min: $yMax1,
                      splitLine: { show: false },
                    },
                    {
                      type: 'value',
                      name: this.$locale('experiment.components.GeWuTest.thoroughfare2'),
                      axisLine: { lineStyle: { color: '#333' } },
                      max: yMax2,
                      min: $yMax2,
                      splitLine: { show: false },
                    },
                  ],
                })
              }
            }
          }
        }
        handlerInterval = setInterval(() => {
          socketChannelData['channelList'] = []
          for (const item of e.childNodes) {
            if (!item.dataset['bind']) break
            const json = JSON.parse(item.dataset['bind'])
            if (json['type'] === 'channelData1') {
              const calculateType = item.dataset['calculateType']
              for (const channelData of json['channelData']) {
                const obj = {
                  channelName: channelData['channelName'],
                  channelAlias: channelData['channelAlias'],
                  type: 1,
                  calculateType: parseInt(calculateType),
                }
                socketChannelData['channelList'].push(obj)
              }
            } else if (json['type'] === 'channelData2') {
              const interval = item.dataset['interval']
              for (const channelData of json['channelData']) {
                if (channelData['channelName'] !== undefined) {
                  const obj = {
                    channelName: channelData['channelName'],
                    channelAlias: channelData['channelAlias'],
                    type: 2,
                    interval: parseInt(interval),
                  }
                  socketChannelData['channelList'].push(obj)
                }
              }
            }
          }
          for (const item of e.childNodes) {
            if (item.classList.contains('work-collection-table')) {
              const bindData = JSON.parse(item.dataset['bind'])
              for (const bindDataItem of bindData) {
                if (bindDataItem['type'] === 1) {
                  const temp = socketChannelData['channelList'].find(channelData => channelData['channelAlias'] === bindDataItem['channelAlias'])
                  if (!temp) {
                    const obj = {
                      channelName: bindDataItem['channelName'],
                      channelAlias: bindDataItem['channelAlias'],
                      type: 1,
                      calculateType: 1,
                    }
                    socketChannelData['channelList'].push(obj)
                  }
                }
              }
            }
            const sessionMeasureListStr = sessionStorage.getItem('measure-series-v2')
            if (sessionMeasureListStr) {
              const sessionMeasureList = JSON.parse(sessionMeasureListStr)
              for (const sessionMeasureListElement of sessionMeasureList) {
                const temp = socketChannelData['channelList'].find(channelData => channelData['channelAlias'] === sessionMeasureListElement['channelAlias'])
                if (!temp) {
                  const obj = {
                    channelName: sessionMeasureListElement['channelName'],
                    channelAlias: sessionMeasureListElement['channelAlias'],
                    type: 1,
                    calculateType: 1,
                  }
                  socketChannelData['channelList'].push(obj)
                }
              }
            }
          }
          socket.send(JSON.stringify(socketChannelData))
        }, 200)
      }
      socket.onerror = (err) => {
        socket.close()
        clearInterval(handlerInterval)
      }
    },
    resetSocket() {
      if (socket) {
        if (handlerInterval) {
          clearInterval(handlerInterval)
        }
        socket.close()
        socket = null
      }
    },
    splitElementsBySplitter(parent = document.body, splitSelector = 'p.tab-module') {
      const children = Array.from(parent.children)
      const splitPoints = []

      children.forEach((child, index) => {
        if (child.matches(splitSelector)) splitPoints.push(index)
      })

      if (!splitPoints.length) return [children]

      const result = []
      let prev = 0

      splitPoints.forEach(current => {
        result.push(children.slice(prev, current))
        prev = current + 1
      })

      result.push(children.slice(prev))

      return result.filter(group => group.length > 0)
    },
    reorganizeStructure(parent = document.body, splitSelector = 'p.tab-module') {
      // 获取所有分割点元素的文本（在 DOM 修改前获取）
      const splitTexts = Array.from(parent.children)
        .filter(child => child.matches(splitSelector))
        .map(el => el.innerText)

      // 执行原有分组和包裹逻辑
      const wrappers = this.splitElementsBySplitter(parent, splitSelector)
        .map(group => {
          const wrapper = document.createElement('div')
          wrapper.className = 'group-wrapper'
          wrapper.append(...group)
          return wrapper
        })

      // 批量替换子元素
      parent.replaceChildren(...wrappers)

      return splitTexts
    },
    makePreviewHtml() {
      const dom = document.querySelector('#teacher-preview')
      const propertyStr = sessionStorage.getItem('property')
      if (propertyStr) {
        const property = JSON.parse(propertyStr)
        const div = document.createElement('div')
        if (property['category']) {
          const category = document.createElement('strong')
          category.innerHTML = '[' + [this.$locale('experiment.components.GeWuTest.physics'), this.$locale('experiment.components.GeWuTest.chemistry'), this.$locale('experiment.components.GeWuTest.biology')][property['category']] + ']'
          div.appendChild(category)
        }

        if (property['keywords']) {
          const keywords = document.createElement('span')
          keywords.innerHTML = '&emsp;关键字：<em>' + property['keywords'] + '</em>'
          div.appendChild(keywords)
        }

        const spanLevel = document.createElement('span')
        spanLevel.innerHTML = '&emsp;等级：<em>' + [this.$locale('experiment.components.GeWuTest.low-level'), this.$locale('experiment.components.GeWuTest.intermediate'), this.$locale('experiment.components.GeWuTest.senior'), this.$locale('experiment.components.GeWuTest.Vocational colleges'), this.$locale('experiment.components.GeWuTest.university')][property['level']] + '</em>'
        div.appendChild(spanLevel)

        const spanDifficulty = document.createElement('span')
        spanDifficulty.innerHTML = '&emsp;难度：<em>' + [this.$locale('experiment.components.GeWuTest.simple and easy'), this.$locale('experiment.components.GeWuTest.medium'), this.$locale('experiment.components.GeWuTest.difficulty')][property['difficulty']] + '</em>'
        div.appendChild(spanDifficulty)

        const spanPreparation = document.createElement('span')
        spanPreparation.innerHTML = '&emsp;准备时间：<em>' + [$locale('experiment.components.GeWuTest.Up to 15 minutes'), $locale('experiment.components.GeWuTest.Up to 30 minutes'), $locale('experiment.components.GeWuTest.Up to 1 hour'), $locale('experiment.components.GeWuTest.More than 1 hour'), $locale('experiment.components.GeWuTest.More than 5 hours')][property['preparation']] + '</em>'
        div.appendChild(spanPreparation)

        const spanExperimental = document.createElement('span')
        spanExperimental.innerHTML = '&emsp;实验时间：<em>' + [$locale('experiment.components.GeWuTest.Up to 15 minutes'), $locale('experiment.components.GeWuTest.Up to 30 minutes'), $locale('experiment.components.GeWuTest.Up to 1 hour'), $locale('experiment.components.GeWuTest.More than 1 hour'), $locale('experiment.components.GeWuTest.More than 5 hours')] + '</em>'
        div.appendChild(spanExperimental)

        dom.insertBefore(div, dom.firstChild)
        if (property['author']) {
          const author = document.createElement('em')
          author.innerHTML = property['author']
          dom.insertBefore(author, dom.firstChild)
        }
        if (property['title']) {
          const title = document.createElement('h1')
          title.innerHTML = '标题：' + property['title']
          dom.insertBefore(title, dom.firstChild)
        }
      }
      const childCustomAnswerList = dom.querySelectorAll('.custom-answer')
      childCustomAnswerList.forEach(item => {
        const trueAnswer = item.innerHTML
        item.innerHTML = ''
        item.contentEditable = true
        item.dataset['trueAnswer'] = trueAnswer
        item.setAttribute('placeholder', this.$locale('experiment.components.GeWuTest.Enter your answer here'))
      })
      const childList = dom.children
      for (let i = 0; i < childList.length; i++) {
        const item = childList[i]
        const backgroundColor = item.style['backgroundColor']
        if (backgroundColor) {
          item.style['backgroundColor'] = 'transparent'
          const span = document.createElement('span')
          span.innerHTML = item.innerHTML
          item.innerHTML = ''
          item.appendChild(span)
          span.style['backgroundColor'] = backgroundColor
        }
        const childCheckboxList = item.querySelectorAll('input[type="checkbox"]')
        childCheckboxList.forEach(item => {
          item.checked = false
        })
        const childSelectList = item.querySelectorAll('select')
        childSelectList.forEach(item => {
          item.selectedIndex = -1
        })
        const childVideoList = item.querySelectorAll('video')
        childVideoList.forEach(item => {
          item.setAttribute('muted', '')
          item.setAttribute('controls', '')
        })
      }
      const config = JSON.parse(sessionStorage.getItem('config')) || {}
      if (config['title']) {
        const documentTitle = document.createElement('div')
        documentTitle.classList.add('document-title')
        documentTitle.innerHTML = config['title']
        documentTitle.style['justifyContent'] = config['align']
        dom.insertBefore(documentTitle, dom.firstChild)
      }
      if (config['author']) {
        const documentAuthor = document.createElement('div')
        documentAuthor.classList.add('document-author')
        documentAuthor.innerHTML = '作者：' + config['author']
        if (dom.querySelector('.document-title')) {
          dom.insertBefore(documentAuthor, dom.firstChild.nextElementSibling)
        } else {
          dom.insertBefore(documentAuthor, dom.firstChild)
        }
      }
      const categories = []
      if (config['category1']) {
        categories.push(config['category1'])
      }
      if (config['category2']) {
        categories.push(config['category2'])
      }
      if (config['category3']) {
        categories.push(config['category3'])
      }
      if (config['category4']) {
        categories.push(config['category4'])
      }
      if (categories.length > 0) {
        const documentCategory = document.createElement('div')
        documentCategory.classList.add('document-category')
        categories.forEach((category, index) => {
          const categoryItem = document.createElement('span')
          categoryItem.innerHTML = category
          categoryItem.classList.add('document-category-item')
          documentCategory.appendChild(categoryItem)
          if (index < categories.length - 1) {
            const i = document.createElement('i')
            i.classList.add('document-category-sp')
            documentCategory.appendChild(i)
          }
        })
        if (dom.querySelector('.document-author')) {
          dom.insertBefore(documentCategory, dom.querySelector('.document-author').nextElementSibling)
        } else if (dom.querySelector('.document-title')) {
          dom.insertBefore(documentCategory, dom.querySelector('.document-title').nextElementSibling)
        } else {
          dom.insertBefore(documentCategory, dom.firstChild)
        }
      }

      dom.querySelectorAll('span.wordDescription').forEach(item => {
        item.addEventListener('click', () => {
          this.$alert(item.dataset['desc'], item.dataset['name'])
        })
      })

      this.tabs = this.reorganizeStructure(dom, 'p.tab-module')
      const allWrapperList = document.querySelectorAll('div.group-wrapper')
      allWrapperList.forEach((itemWrapper, index) => {
        if (0 === index) {
          itemWrapper.style.display = 'block'
        } else {
          itemWrapper.style.display = 'none'
        }
      })
      for (const collection of dom.querySelectorAll('section.work-collection')) {
        console.log(collection)
        // collection 每一组工作集
        const collectionDiv = document.createElement('div')
        const collectionDivHeader = document.createElement('div')
        const collectionDivHeaderTitle = document.createElement('div')
        const collectionDivHeaderButtonStart = document.createElement('div')
        collectionDivHeaderButtonStart.innerHTML = '开始'
        this.bindStyle(collectionDivHeaderButtonStart, {
          fontSize: '12px',
          borderRadius: '4px',
          padding: '4px 8px',
          color: '#fff',
          cursor: 'pointer',
          background: '#b6b6b6',
        })
        this.bindStyle(collectionDivHeaderTitle, {
          fontSize: '16px',
        })
        const collectionDivHeaderButtonEnd = document.createElement('div')
        collectionDivHeaderButtonEnd.innerHTML = '结束'
        this.bindStyle(collectionDivHeaderButtonEnd, {
          fontSize: '12px',
          borderRadius: '4px',
          padding: '4px 8px',
          color: '#fff',
          cursor: 'pointer',
          background: '#b6b6b6',
          display: 'none',
        })
        const collectionDivHeaderButtonSave = document.createElement('div')
        collectionDivHeaderButtonSave.innerHTML = '保存'
        this.bindStyle(collectionDivHeaderButtonSave, {
          fontSize: '12px',
          borderRadius: '4px',
          padding: '4px 8px',
          color: '#fff',
          cursor: 'pointer',
          background: '#b6b6b6',
          display: 'none',
        })
        if (collection.classList.contains('chart1')) {
          collectionDivHeaderTitle.innerHTML = '万用表'
        } else if (collection.classList.contains('chart2')) {
          collectionDivHeaderTitle.innerHTML = '示波器'
        } else {
          collectionDivHeaderTitle.innerHTML = '工作集'
        }

        collectionDivHeaderButtonStart.onclick = (e) => {
          const parent = e.target.parentNode
          parent.style.width = '180px'
          e.target.style.display = 'none'
          parent.dataset['status'] = 'starting'
          parent.querySelector('div:nth-child(3)').style.display = 'block'
          parent.querySelector('div:nth-child(4)').style.display = 'block'
          const initParent = e.target.parentNode.parentNode
          const initPanelDom = initParent.childNodes[1]
          this.initSocket(initPanelDom)
        }
        collectionDivHeaderButtonEnd.onclick = (e) => {
          const parent = e.target.parentNode
          e.target.style.display = 'none'
          parent.dataset['status'] = 'stop'
          parent.querySelector('div:nth-child(4)').style.display = 'none'
          parent.style.width = '88px'
          this.resetSocket()
          const tempTop = collectionDivHeaderButtonEnd.parentNode.parentNode
          const dataArea = tempTop.childNodes[1]
          dataArea.querySelectorAll('div.multimeter-value').forEach(multimeter => {
            multimeter.parentNode.parentNode.dataset['lastestValue'] = multimeter.innerHTML
          })
          dataArea.querySelectorAll('div.work-collection-chart').forEach(collectionChart => {
            const chartInstance = measureInstanceMap.get(collectionChart.childNodes[0])
            const chartOption = chartInstance.getOption()
            collectionChart.dataset['lastOption'] = JSON.stringify(chartOption)
          })
          dataArea.querySelectorAll('div.chart-div').forEach(chartDiv => {
            const chartInstance = chartInstanceMap.get(chartDiv)
            const chartOption = chartInstance.getOption()
            chartDiv.dataset['lastOption'] = JSON.stringify(chartOption)
          })
        }
        collectionDivHeaderButtonSave.onclick = (e) => {
          const parent = e.target.parentNode.parentNode
          const panelDom = parent.childNodes[1]
          for (const item of panelDom.querySelectorAll('.work-collection-table')) {
            const json = JSON.parse(item.dataset['bind'])
            // calculateFormula
            const tr = document.createElement('tr')
            for (const jsonItem of json) {
              if (jsonItem['type'] === 1) {
                const td = document.createElement('td')
                td.innerHTML = currentSocketData[jsonItem['channelAlias']]
                tr.appendChild(td)
              } else if (jsonItem['type'] === 2) {
                const td = document.createElement('td')
                const value = parseFloat(this.calculateFormula(jsonItem['calculate']).toFixed(5))
                currentSocketData[jsonItem['channelAlias']] = value
                td.innerHTML = value
                tr.appendChild(td)
              }
              item.querySelector('tbody').appendChild(tr)
            }
          }
          currentSocketDataList.push({ ...currentSocketData })
          panelDom.querySelectorAll('.work-collection-chart').forEach(item => {
            const jsonAxisX = JSON.parse(item.dataset['xAxis'])
            const jsonAxisYList = JSON.parse(item.dataset['yAxis'])
            const xAxisData = []
            const seriesList = []
            for (let i = 0; i < jsonAxisYList.length; i++) {
              seriesList.push([])
            }
            for (const currentSocketDataListElement of currentSocketDataList) {
              xAxisData.push(currentSocketDataListElement[jsonAxisX])
              for (let i = 0; i < jsonAxisYList.length; i++) {
                const yAxisDataAlias = jsonAxisYList[i]
                seriesList[i].push(currentSocketDataListElement[yAxisDataAlias])
              }
            }
            const series = []
            for (const seriesData of seriesList) {
              const seriesItem = {
                type: 'line',
                data: seriesData,
              }
              series.push(seriesItem)
            }
            if (measureInstanceMap.has(item.querySelector('div'))) {
              measureInstanceMap.get(item.querySelector('div')).setOption({
                xAxis: {
                  data: xAxisData,
                },
                series,
              })
            }
          })
        }
        collectionDivHeader.appendChild(collectionDivHeaderTitle)
        collectionDivHeader.appendChild(collectionDivHeaderButtonStart)
        collectionDivHeader.appendChild(collectionDivHeaderButtonEnd)
        collectionDivHeader.appendChild(collectionDivHeaderButtonSave)
        this.bindStyle(collectionDivHeader, {
          width: '132px',
          height: '40px',
          backgroundColor: '#434343',
          color: '#f0f0f0',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'space-around',
          userSelect: 'none',
        })
        collectionDivHeader.dataset['status'] = 'none'
        const collectionDivBound = document.createElement('div')
        this.bindStyle(collectionDivBound, {
          border: '1px solid #333',
          padding: '12px 12px 0 12px',
          boxSizing: 'border-box',
        })
        for (const item of collection.querySelectorAll('section')) {
          // item 每组工作集中的工作对象
          const className = item.className
          if (className === 'work-collection-multimeter') {
            // 万用表
            const bindChannelData = JSON.parse(item.dataset['channelData'])
            this.createDataViewMultimeter(bindChannelData, collectionDivBound)
          } else if (className === 'work-collection-oscilloscope') {
            // 示波器
            const bindChannelData = JSON.parse(item.dataset['channelData'])
            this.createDataViewOscilloscope(bindChannelData, collectionDivBound)
          } else if (className === 'work-collection-measure-table') {
            // 测量数据表格
            const bindMeasureList = JSON.parse(item.dataset['measureList'])
            this.createDataViewMeasureList(bindMeasureList, collectionDivBound)
          } else if (className === 'work-collection-measure-view') {
            // 测量数据视图
            const bindXAxis = JSON.parse(item.dataset['xAxis'])
            const bindYAxis = JSON.parse(item.dataset['yAxis'])
            this.createDataViewMeasureView(bindXAxis, bindYAxis, collectionDivBound)
          }
        }
        collectionDiv.appendChild(collectionDivHeader)
        collectionDiv.appendChild(collectionDivBound)
        collection.innerHTML = ''
        collection.appendChild(collectionDiv)
      }
    },
    calculateFormula(formula) {
      const context = {
        ...currentSocketData,
        Math: Math, // 允许使用Math函数
      }
      const variableNames = Object.keys(context)
      const args = variableNames.join(', ')
      const functionBody = `return ${formula};`
      try {
        // 使用Function构造函数创建计算函数
        const calculator = new Function(args, functionBody)

        // 按顺序传入所有变量值
        const values = variableNames.map(name => context[name])

        // 执行计算并返回结果
        return calculator(...values)
      } catch (error) {
        console.error('公式计算错误:', error)
        return NaN
      }
    },
    createDataViewMeasureView(xAxis, yAxisList, collection) {
      const chartDom = document.createElement('div')
      chartDom.dataset['xAxis'] = JSON.stringify(xAxis)
      chartDom.dataset['yAxis'] = JSON.stringify(yAxisList)
      chartDom.classList.add('work-collection-chart')
      this.bindStyle(chartDom, {
        width: '800px',
        height: '320px',
        backgroundColor: '#474747',
        marginBottom: '12px',
        borderRadius: '6px',
        boxSizing: 'border-box',
        padding: '12px',
      })
      const chartInstanceDom = document.createElement('div')
      this.bindStyle(chartInstanceDom, {
        width: '100%',
        height: '100%',
      })
      chartDom.appendChild(chartInstanceDom)
      collection.appendChild(chartDom)
      const instance = echarts.init(chartInstanceDom)
      measureInstanceMap.set(chartInstanceDom, instance)
      resizeObserver.observe(chartInstanceDom)
      instance.setOption({
        xAxis: {
          type: 'category',
          splitLine: {
            show: false,
          },
          axisLine: {
            lineStyle: {
              color: '#b6b6b6',
            },
          },
        },
        yAxis: {
          splitLine: {
            show: false,
          },
          axisLine: {
            lineStyle: {
              color: '#b6b6b6',
            },
          },
        },
        grid: {
          left: 32,
          right: 32,
          top: 32,
          bottom: 32,
        },
      })
    },
    createDataViewMeasureList(measureList, collection) {
      const tableDiv = document.createElement('div')
      tableDiv.dataset['bind'] = JSON.stringify(measureList)
      tableDiv.classList.add('work-collection-table')
      this.bindStyle(tableDiv, {
        width: '100%',
        marginBottom: '12px',
      })
      const table = document.createElement('table')
      this.bindStyle(table, {
        width: '100%',
      })
      const thead = document.createElement('thead')
      tableDiv.appendChild(table)
      collection.appendChild(tableDiv)
      const tr1 = document.createElement('tr')
      table.appendChild(thead)
      thead.appendChild(tr1)
      const tbody = document.createElement('tbody')
      table.appendChild(tbody)
      for (const measure of measureList) {
        const th1 = document.createElement('th')
        th1.innerHTML = `${measure['label']}(${measure['unit']})`
        tr1.appendChild(th1)
      }
    },
    createDataViewOscilloscope(channelData, collection) {
      const oscilloscope = document.createElement('div')
      oscilloscope.classList.add('oscilloscope')
      oscilloscope.dataset['bind'] = JSON.stringify({
        type: 'channelData2',
        channelData,
      })
      oscilloscope.dataset['interval'] = '1'
      oscilloscope.dataset['yMax1'] = '2'
      oscilloscope.dataset['yMax2'] = '2'
      this.bindStyle(oscilloscope, {
        width: '800px',
        height: '520px',
        borderRadius: '6px',
        backgroundColor: '#474747',
        boxSizing: 'border-box',
        padding: '12px',
        marginBottom: '12px',
        userSelect: 'none',
      })
      const oscilloscopePanel = document.createElement('div')
      this.bindStyle(oscilloscopePanel, {
        height: '320px',
        borderRadius: '6px',
        backgroundColor: '#919191',
        boxSizing: 'border-box',
        padding: '12px',
      })
      // chartInstanceMap
      const chartDiv = document.createElement('div')
      this.bindStyle(chartDiv, {
        width: '100%',
        height: '100%',
      })
      chartDiv.classList.add('chart-div')
      oscilloscopePanel.appendChild(chartDiv)
      const chartInstance = echarts.init(chartDiv)
      chartInstance.setOption({
        xAxis: {
          type: 'category',
          axisLabel: {
            show: false,
          },
          axisLine: {
            lineStyle: {
              color: '#333',
            },
            show: false,
          },
          splitLine: {
            show: false,
          },
        },
        yAxis: [
          {
            type: 'value',
            name: this.$locale('experiment.components.GeWuTest.thoroughfare1'),
            axisLine: { lineStyle: { color: '#333' } },
            max: 2,
            min: -2,
            splitLine: { show: false },
          },
          {
            type: 'value',
            name: this.$locale('experiment.components.GeWuTest.thoroughfare2'),
            axisLine: { lineStyle: { color: '#333' } },
            max: 2,
            min: -2,
            splitLine: { show: false },
          },
        ],
        grid: {
          left: 32,
          top: 32,
          bottom: 32,
          right: 40,
        },
      })
      chartInstanceMap.set(chartDiv, chartInstance)
      chartInstanceKeys.push(chartDiv)
      resizeObserver.observe(chartDiv)
      const oscilloscopeButtonBound = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBound, {
        height: '164px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'space-around',
        marginTop: '12px',
      })
      const oscilloscopeButtonBlock1 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock1, {
        width: '210px',
        height: '164px',
        position: 'relative',
      })
      const oscilloscopeButtonBlock1Axis = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock1Axis, {
        width: '164px',
        height: '16px',
        border: '2px solid #ffffff',
        boxSizing: 'border-box',
        borderRadius: '6px',
        top: '50%',
        left: '0',
        zIndex: '10',
        transform: 'translateY(-50%)',
        position: 'absolute',
      })
      const oscilloscopeButtonBlock1AxisButton = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock1AxisButton, {
        width: '20px',
        height: '32px',
        top: '50%',
        left: '0',
        zIndex: '20',
        borderRadius: '6px',
        transform: 'translateY(-50%)',
        border: '1px solid #ffffff',
        backgroundColor: '#cfcfcf',
        cursor: 'pointer',
        position: 'absolute',
      })
      oscilloscopeButtonBlock1AxisButton.onclick = (e) => {
        // 间隔更新
        const left = e.target.style['left']
        if (left === '0px') {
          e.target.style['left'] = '30px'
          oscilloscopeButtonBlock1AxisButton.parentNode.parentNode.parentNode.dataset['interval'] = '2'
        } else if (left === '30px') {
          e.target.style['left'] = '60px'
          oscilloscopeButtonBlock1AxisButton.parentNode.parentNode.parentNode.dataset['interval'] = '3'
        } else if (left === '60px') {
          e.target.style['left'] = '90px'
          oscilloscopeButtonBlock1AxisButton.parentNode.parentNode.parentNode.dataset['interval'] = '4'
        } else if (left === '90px') {
          e.target.style['left'] = '120px'
          oscilloscopeButtonBlock1AxisButton.parentNode.parentNode.parentNode.dataset['interval'] = '5'
        } else if (left === '120px') {
          e.target.style['left'] = '150px'
          oscilloscopeButtonBlock1AxisButton.parentNode.parentNode.parentNode.dataset['interval'] = '6'
        } else if (left === '150px') {
          e.target.style['left'] = '0px'
          oscilloscopeButtonBlock1AxisButton.parentNode.parentNode.parentNode.dataset['interval'] = '7'
        }
      }
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Axis)
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1AxisButton)
      const oscilloscopeButtonBlock1Label1 = document.createElement('div')
      oscilloscopeButtonBlock1Label1.innerHTML = '100us'
      this.bindStyle(oscilloscopeButtonBlock1Label1, {
        position: 'absolute',
        left: '0',
        top: '22%',
        color: '#ffffff',
      })
      const oscilloscopeButtonBlock1Label2 = document.createElement('div')
      oscilloscopeButtonBlock1Label2.innerHTML = '10us'
      this.bindStyle(oscilloscopeButtonBlock1Label2, {
        position: 'absolute',
        left: '30px',
        bottom: '22%',
        color: '#ffffff',
      })
      const oscilloscopeButtonBlock1Label3 = document.createElement('div')
      oscilloscopeButtonBlock1Label3.innerHTML = '100ms'
      this.bindStyle(oscilloscopeButtonBlock1Label3, {
        position: 'absolute',
        left: '60px',
        top: '22%',
        color: '#ffffff',
      })
      const oscilloscopeButtonBlock1Label4 = document.createElement('div')
      oscilloscopeButtonBlock1Label4.innerHTML = '10ms'
      this.bindStyle(oscilloscopeButtonBlock1Label4, {
        position: 'absolute',
        left: '90px',
        bottom: '22%',
        color: '#ffffff',
      })
      const oscilloscopeButtonBlock1Label5 = document.createElement('div')
      oscilloscopeButtonBlock1Label5.innerHTML = '2ms'
      this.bindStyle(oscilloscopeButtonBlock1Label5, {
        position: 'absolute',
        left: '120px',
        top: '22%',
        color: '#ffffff',
      })
      const oscilloscopeButtonBlock1Label6 = document.createElement('div')
      oscilloscopeButtonBlock1Label6.innerHTML = '1ms'
      this.bindStyle(oscilloscopeButtonBlock1Label6, {
        position: 'absolute',
        left: '150px',
        bottom: '22%',
        color: '#ffffff',
      })
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Label1)
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Label2)
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Label3)
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Label4)
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Label5)
      oscilloscopeButtonBlock1.appendChild(oscilloscopeButtonBlock1Label6)
      oscilloscopeButtonBound.appendChild(oscilloscopeButtonBlock1)
      // 第二个面板
      const oscilloscopeButtonBlock2 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2, {
        width: '164px',
        height: '164px',
        position: 'relative',
      })
      const oscilloscopeButtonBlock2Circle = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2Circle, {
        width: '124px',
        height: '124px',
        position: 'absolute',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        borderRadius: '50%',
        backgroundColor: '#ccc',
      })
      const oscilloscopeButtonBlock2CircleLabel1 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel1, {
        position: 'absolute',
        top: '0px',
        left: '50%',
        transform: 'translateX(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel1.innerHTML = '2V'
      const oscilloscopeButtonBlock2CircleLabel2 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel2, {
        position: 'absolute',
        top: '20px',
        right: '12px',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel2.innerHTML = '5V'
      const oscilloscopeButtonBlock2CircleLabel3 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel3, {
        position: 'absolute',
        top: '50%',
        right: '-8px',
        transform: 'translateY(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel3.innerHTML = '10V'
      const oscilloscopeButtonBlock2CircleLabel4 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel4, {
        position: 'absolute',
        bottom: '20px',
        right: '12px',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel4.innerHTML = '20V'
      const oscilloscopeButtonBlock2CircleLabel5 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel5, {
        position: 'absolute',
        bottom: '0px',
        left: '50%',
        transform: 'translateX(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel5.innerHTML = '50V'
      const oscilloscopeButtonBlock2CircleLabel6 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel6, {
        position: 'absolute',
        bottom: '20px',
        left: '12px',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel6.innerHTML = '100V'
      const oscilloscopeButtonBlock2CircleLabel7 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CircleLabel7, {
        position: 'absolute',
        top: '50%',
        left: '-12px',
        transform: 'translateY(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock2CircleLabel7.innerHTML = '200V'
      const oscilloscopeButtonBlock2CirclePoint = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock2CirclePoint, {
        width: '16px',
        height: '112px',
        borderTopLeftRadius: '50%',
        borderTopRightRadius: '50%',
        border: '1px solid #474747',
        backgroundColor: '#ffffff',
        position: 'absolute',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        transformOrigin: 'center center',
      })
      oscilloscopeButtonBlock2CirclePoint.onclick = (e) => {
        const transform = e.target.style['transform']
        if (transform === 'translate(-50%, -50%)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(45deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '5'
        } else if (transform === 'translate(-50%, -50%) rotate(45deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(90deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '10'
        } else if (transform === 'translate(-50%, -50%) rotate(90deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(135deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '20'
        } else if (transform === 'translate(-50%, -50%) rotate(135deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(180deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '50'
        } else if (transform === 'translate(-50%, -50%) rotate(180deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(225deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '100'
        } else if (transform === 'translate(-50%, -50%) rotate(225deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(270deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '200'
        } else if (transform === 'translate(-50%, -50%) rotate(270deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax1'] = '2'
        }
      }
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2Circle)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel1)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel2)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel3)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel4)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel5)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel6)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CircleLabel7)
      oscilloscopeButtonBlock2.appendChild(oscilloscopeButtonBlock2CirclePoint)
      oscilloscopeButtonBound.appendChild(oscilloscopeButtonBlock2)
      // 第三个面板
      const oscilloscopeButtonBlock3 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3, {
        width: '164px',
        height: '164px',
        position: 'relative',
      })
      const oscilloscopeButtonBlock3Circle = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3Circle, {
        width: '124px',
        height: '124px',
        position: 'absolute',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        borderRadius: '50%',
        backgroundColor: '#ccc',
      })
      const oscilloscopeButtonBlock3CircleLabel1 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel1, {
        position: 'absolute',
        top: '0px',
        left: '50%',
        transform: 'translateX(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel1.innerHTML = '2V'
      const oscilloscopeButtonBlock3CircleLabel2 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel2, {
        position: 'absolute',
        top: '20px',
        right: '12px',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel2.innerHTML = '5V'
      const oscilloscopeButtonBlock3CircleLabel3 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel3, {
        position: 'absolute',
        top: '50%',
        right: '-8px',
        transform: 'translateY(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel3.innerHTML = '10V'
      const oscilloscopeButtonBlock3CircleLabel4 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel4, {
        position: 'absolute',
        bottom: '20px',
        right: '12px',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel4.innerHTML = '20V'
      const oscilloscopeButtonBlock3CircleLabel5 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel5, {
        position: 'absolute',
        bottom: '0px',
        left: '50%',
        transform: 'translateX(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel5.innerHTML = '50V'
      const oscilloscopeButtonBlock3CircleLabel6 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel6, {
        position: 'absolute',
        bottom: '20px',
        left: '12px',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel6.innerHTML = '100V'
      const oscilloscopeButtonBlock3CircleLabel7 = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CircleLabel7, {
        position: 'absolute',
        top: '50%',
        left: '-12px',
        transform: 'translateY(-50%)',
        color: '#ffffff',
        fontSize: '12px',
      })
      oscilloscopeButtonBlock3CircleLabel7.innerHTML = '200V'
      const oscilloscopeButtonBlock3CirclePoint = document.createElement('div')
      this.bindStyle(oscilloscopeButtonBlock3CirclePoint, {
        width: '16px',
        height: '112px',
        borderTopLeftRadius: '50%',
        borderTopRightRadius: '50%',
        border: '1px solid #474747',
        backgroundColor: '#ffffff',
        position: 'absolute',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        transformOrigin: 'center center',
      })
      oscilloscopeButtonBlock3CirclePoint.onclick = (e) => {
        const transform = e.target.style['transform']
        if (transform === 'translate(-50%, -50%)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(45deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '5'
        } else if (transform === 'translate(-50%, -50%) rotate(45deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(90deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '10'
        } else if (transform === 'translate(-50%, -50%) rotate(90deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(135deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '20'
        } else if (transform === 'translate(-50%, -50%) rotate(135deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(180deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '50'
        } else if (transform === 'translate(-50%, -50%) rotate(180deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(225deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '100'
        } else if (transform === 'translate(-50%, -50%) rotate(225deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(270deg)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '200'
        } else if (transform === 'translate(-50%, -50%) rotate(270deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%)'
          e.target.parentNode.parentNode.parentNode.dataset['yMax2'] = '2'
        }
      }
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3Circle)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel1)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel2)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel3)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel4)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel5)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel6)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CircleLabel7)
      oscilloscopeButtonBlock3.appendChild(oscilloscopeButtonBlock3CirclePoint)
      oscilloscopeButtonBound.appendChild(oscilloscopeButtonBlock3)
      oscilloscope.appendChild(oscilloscopePanel)
      oscilloscope.appendChild(oscilloscopeButtonBound)
      collection.appendChild(oscilloscope)
    },
    createDataViewMultimeter(channelData, collection) {
      const multimeter = document.createElement('div')
      multimeter.classList.add('multimeter')
      multimeter.dataset['bind'] = JSON.stringify({
        type: 'channelData1',
        channelData,
      })
      multimeter.dataset['calculateType'] = '1'
      this.bindStyle(multimeter, {
        width: '340px',
        height: '420px',
        borderRadius: '6px',
        backgroundColor: '#474747',
        boxSizing: 'border-box',
        padding: '12px',
        marginBottom: '12px',
      })
      const multimeterPanel = document.createElement('div')
      this.bindStyle(multimeterPanel, {
        width: '100%',
        height: '168px',
        borderRadius: '6px',
        backgroundColor: '#ffffff',
        position: 'relative',
      })
      const multimeterPanelValue = document.createElement('div')
      multimeterPanelValue.classList.add('multimeter-value')
      this.bindStyle(multimeterPanelValue, {
        fontSize: '40px',
        fontWeight: '600',
        color: '#333',
        position: 'absolute',
        left: '50%',
        top: '50%',
        userSelect: 'none',
        transform: 'translate(-50%, -50%)',
      })
      const multimeterPanelUnit = document.createElement('div')
      multimeterPanelUnit.classList.add('multimeter-panel-unit')
      this.bindStyle(multimeterPanelUnit, {
        fontSize: '32px',
        fontWeight: '600',
        position: 'absolute',
        right: '20px',
        bottom: '20px',
        userSelect: 'none',
      })
      const multimeterPanelTitle = document.createElement('div')
      this.bindStyle(multimeterPanelTitle, {
        fontSize: '22px',
        fontWeight: '600',
        position: 'absolute',
        left: '10px',
        top: '10px',
        userSelect: 'none',
      })
      const multimeterButtonBound = document.createElement('div')
      this.bindStyle(multimeterButtonBound, {
        height: '216px',
        marginTop: '12px',
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
      })
      const multimeterButtonBlock = document.createElement('div')
      this.bindStyle(multimeterButtonBlock, {
        width: '192px',
        height: '192px',
        borderRadius: '50%',
        backgroundColor: '#cdcdcd',
        position: 'relative',
      })
      const multimeterButtonBlockPoint = document.createElement('div')
      this.bindStyle(multimeterButtonBlockPoint, {
        width: '24px',
        height: '180px',
        border: '2px solid #474747',
        backgroundColor: '#ffffff',
        borderRadius: '6px',
        position: 'absolute',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        transformOrigin: 'center center',
      })
      multimeterButtonBlockPoint.onclick = (e) => {
        const transform = e.target.style['transform']
        if (transform === 'translate(-50%, -50%)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(60deg)'
          e.target.parentNode.parentNode.parentNode.querySelector('.multimeter-panel-unit').innerHTML = 'V~'
          e.target.parentNode.parentNode.parentNode.dataset['calculateType'] = '3'
        } else if (transform === 'translate(-50%, -50%) rotate(60deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(120deg)'
          e.target.parentNode.parentNode.parentNode.querySelector('.multimeter-panel-unit').innerHTML = 'A~'
          e.target.parentNode.parentNode.parentNode.dataset['calculateType'] = '4'
        } else if (transform === 'translate(-50%, -50%) rotate(120deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(180deg)'
          e.target.parentNode.parentNode.parentNode.querySelector('.multimeter-panel-unit').innerHTML = 'A'
          e.target.parentNode.parentNode.parentNode.dataset['calculateType'] = '2'
        } else if (transform === 'translate(-50%, -50%) rotate(180deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(240deg)'
          e.target.parentNode.parentNode.parentNode.querySelector('.multimeter-panel-unit').innerHTML = 'Ω'
          e.target.parentNode.parentNode.parentNode.dataset['calculateType'] = '5'
        } else if (transform === 'translate(-50%, -50%) rotate(240deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%) rotate(300deg)'
          e.target.parentNode.parentNode.parentNode.querySelector('.multimeter-panel-unit').innerHTML = 'F'
          e.target.parentNode.parentNode.parentNode.dataset['calculateType'] = '6'
        } else if (transform === 'translate(-50%, -50%) rotate(300deg)') {
          e.target.style['transform'] = 'translate(-50%, -50%)'
          e.target.parentNode.parentNode.parentNode.querySelector('.multimeter-panel-unit').innerHTML = 'V'
          e.target.parentNode.parentNode.parentNode.dataset['calculateType'] = '1'
        }
      }
      const multimeterButtonBlockPointBefore = document.createElement('div')
      this.bindStyle(multimeterButtonBlockPointBefore, {
        width: '12px',
        height: '28px',
        backgroundColor: '#474747',
        borderRadius: '6px',
        position: 'absolute',
        left: '50%',
        top: '6px',
        transform: 'translateX(-50%)',
      })
      const multimeterButtonBlockLabel1 = document.createElement('div')
      multimeterButtonBlockLabel1.innerHTML = 'V'
      this.bindStyle(multimeterButtonBlockLabel1, {
        position: 'absolute',
        left: '50%',
        top: '-22px',
        color: '#ffffff',
        transform: 'translateX(-50%)',
      })
      const multimeterButtonBlockLabel2 = document.createElement('div')
      multimeterButtonBlockLabel2.innerHTML = 'V~'
      this.bindStyle(multimeterButtonBlockLabel2, {
        position: 'absolute',
        right: '-16px',
        top: '25px',
        color: '#ffffff',
      })
      const multimeterButtonBlockLabel3 = document.createElement('div')
      multimeterButtonBlockLabel3.innerHTML = 'A~'
      this.bindStyle(multimeterButtonBlockLabel3, {
        position: 'absolute',
        right: '-16px',
        bottom: '25px',
        color: '#ffffff',
      })
      const multimeterButtonBlockLabel4 = document.createElement('div')
      multimeterButtonBlockLabel4.innerHTML = 'A'
      this.bindStyle(multimeterButtonBlockLabel4, {
        position: 'absolute',
        left: '50%',
        bottom: '-22px',
        color: '#ffffff',
        transform: 'translateX(-50%)',
      })
      const multimeterButtonBlockLabel5 = document.createElement('div')
      multimeterButtonBlockLabel5.innerHTML = 'Ω'
      this.bindStyle(multimeterButtonBlockLabel5, {
        position: 'absolute',
        left: '-16px',
        bottom: '25px',
        color: '#ffffff',
      })
      const multimeterButtonBlockLabel6 = document.createElement('div')
      multimeterButtonBlockLabel6.innerHTML = 'F'
      this.bindStyle(multimeterButtonBlockLabel6, {
        position: 'absolute',
        left: '-10px',
        top: '25px',
        color: '#ffffff',
      })
      multimeterPanelUnit.innerHTML = 'v'
      multimeterPanelValue.innerHTML = '0.00'
      multimeterPanelTitle.innerHTML = '万用表'
      multimeterPanel.appendChild(multimeterPanelValue)
      multimeterPanel.appendChild(multimeterPanelUnit)
      multimeterPanel.appendChild(multimeterPanelTitle)
      multimeterButtonBound.appendChild(multimeterButtonBlock)
      multimeterButtonBlock.appendChild(multimeterButtonBlockLabel1)
      multimeterButtonBlock.appendChild(multimeterButtonBlockLabel2)
      multimeterButtonBlock.appendChild(multimeterButtonBlockLabel3)
      multimeterButtonBlock.appendChild(multimeterButtonBlockLabel4)
      multimeterButtonBlock.appendChild(multimeterButtonBlockLabel5)
      multimeterButtonBlock.appendChild(multimeterButtonBlockLabel6)
      multimeterButtonBlock.appendChild(multimeterButtonBlockPoint)
      multimeterButtonBlockPoint.appendChild(multimeterButtonBlockPointBefore)
      multimeter.appendChild(multimeterPanel)
      multimeter.appendChild(multimeterButtonBound)
      collection.appendChild(multimeter)
    },
    bindStyle(dom, styleObject) {
      for (const styleKey in styleObject) {
        dom.style[styleKey] = styleObject[styleKey]
      }
    },
    $submit() {
      return new Promise((resolve, reject) => {
        const dom = document.querySelector('#teacher-preview')
        dom.querySelectorAll('input[type="checkbox"]').forEach(input => {
          input.dataset['lastChecked'] = input.checked
        })
        dom.querySelectorAll('select').forEach(select => {
          select.dataset['lastSelected'] = select.selectedIndex.toString()
        })
        dom.querySelectorAll('p.custom-answer').forEach(answer => {
          answer.contentEditable = false
        })
        dom.querySelectorAll('div.work-collection-chart').forEach(chart => {
          chart.innerHTML = ''
        })
        dom.querySelectorAll('div.chart-div').forEach(chart => {
          chart.innerHTML = ''
        })
        let lastHtml = ''
        dom.querySelectorAll('div.group-wrapper').forEach(group => {
          lastHtml = lastHtml + group.outerHTML
        })
        apiStudentSaveWork(this.$props.testId, lastHtml).then(() => {
          resolve()
        }).catch(reject)
      })
    }
  },
}
</script>

<template>
  <div class="dialog-ge-wu-test-container">
    <div id="teacher-preview" class="project-settings-page-teacher-preview" v-html="currentHtml" />
    <div class="tabs-container">
      <div class="tabs-item" :class="currentTab === 0 ? '--active' : ''" :style="{ '--length': tabs.length + 1 }"
           @click="handleChangeTab(0)">默认分页
      </div>
      <div class="tabs-item" :class="currentTab === (index + 1) ? '--active' : ''" v-for="(tab, index) in tabs"
           :style="{ '--length': tabs.length + 1 }" :key="index" @click="handleChangeTab(index + 1)">{{ tab }}
      </div>
    </div>
  </div>
</template>

<style lang="scss">
.dialog-ge-wu-test-container {
  position: relative;
  display: flex;
  justify-content: center;
  height: 100%;
  overflow-y: auto;
}

.socket-panel {
  position: absolute;
  right: 12px;
  top: 12px;
}

.tabs-container {
  position: absolute;
  height: 60px;
  width: 100%;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  z-index: 100;
  display: flex;

  .tabs-item {
    position: relative;
    width: calc(100% / var(--length));
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    user-select: none;

    &.--active {
      background-color: #e81b46;
      color: #fff;
    }
  }
}

.project-settings-page-teacher-preview {
  height: calc(100% - 68px);
  padding: 12px 12px 0 12px;
  overflow-y: auto;
  background-color: #ffffff;
  border: 1px solid #C6C6C6;
  width: 100%;
  outline: none;
  box-sizing: border-box;

  .group-wrapper {
    display: none;
    height: 100%;
    overflow-y: auto;
  }

  .document-title {
    font-size: 22px;
    font-weight: 600;
    margin-bottom: 12px;
    display: flex;
    align-items: center;
  }

  .document-author {
    font-size: 15px;
    color: #666666;
    margin-bottom: 12px;
  }

  .document-category {
    display: flex;
    align-items: center;
    font-size: 12px;
    margin-bottom: 12px;

    .document-category-item {
      color: #888888;
    }

    .document-category-sp {
      margin: 0 4px;

      &::before {
        content: '>';
      }
    }
  }

  p {
    //border-left: 8px solid #6d6d6d;
    padding: 8px 0 8px 4px;

    .wordDescription {
      color: #fff; /* 文字颜色 */
      text-shadow: 0 0 5px #ff0000,
      0 0 10px #ff0000,
      0 0 20px #ff0000;
      user-select: none;
      cursor: pointer;
    }

    &.head1 {
      font-size: 32px;
      font-weight: 700;
    }

    &.head2 {
      font-size: 24px;
      font-weight: 700;
    }

    &.head3 {
      font-size: 18px;
      font-weight: 700;
    }

    &.head4 {
      font-weight: 700;
    }

    &.head5 {
      font-size: 13px;
      font-weight: 700;
    }

    &.head6 {
      font-size: 12px;
      font-weight: 700;
    }

    &.title {
      font-size: 21px;
      text-align: center;
    }

    &.sub-title {
      font-size: 21px;
      font-weight: 600;
      text-align: center;
    }

    &.normal {
      font-size: 14px;
      font-weight: 600;
      font-style: italic;
    }

    &.custom-list {
      font-size: 14px;
      height: 32px;
      padding: 0;
      border-left: 12px solid #B4D8E2;
    }

    &.custom-tips {
      background-color: rgba(85, 170, 255, 0.5);
      border: 3px solid #55aaff;
      padding: 8px;
      border-radius: 6px;
      margin: 8px 0;
    }

    &.custom-warning {
      padding: 8px;
      border-radius: 6px;
      background-color: #F49193;
      border: 3px solid #C74D4F;
      margin: 8px 0;
    }

    &.custom-answer {
      padding: 8px;
      border-radius: 6px;
      background-color: #EEEEED;
      margin: 8px 0;
    }
  }

  table.custom-material {
    width: 80%;
    border-left: 1px solid #dcdfe6;
    border-top: 1px solid #dcdfe6;

    thead {
      background-color: #ffffff;
      font-size: 14px;

      tr {
        th {
          padding: 12px;
          border-right: 1px solid #dcdfe6;
          border-bottom: 1px solid #dcdfe6;
        }
      }
    }

    tbody {
      background-color: #ffffff;

      tr {
        td {
          padding: 12px;
          border-right: 1px solid #dcdfe6;
          border-bottom: 1px solid #dcdfe6;
        }
      }
    }
  }

  table.custom-device {
    border-left: 1px solid #dcdfe6;
    border-top: 1px solid #dcdfe6;

    thead {
      background-color: #ffffff;
      font-size: 14px;

      tr {
        th {
          padding: 12px;
          border-right: 1px solid #dcdfe6;
          border-bottom: 1px solid #dcdfe6;
        }
      }
    }

    tbody {
      background-color: #ffffff;

      tr {
        td {
          padding: 12px;
          border-right: 1px solid #dcdfe6;
          border-bottom: 1px solid #dcdfe6;
        }
      }
    }
  }

  .measure-table {
    width: 100%;
    border-left: 1px solid #dcdfe6;
    border-top: 1px solid #dcdfe6;

    thead {
      background-color: #FFFFFF;
      font-size: 14px;

      tr {
        th {
          padding: 12px 0;
          border-right: 1px solid #dcdfe6;
          border-bottom: 1px solid #dcdfe6;
          background-color: #dcdfe6;
          color: #333;
        }
      }
    }

    tbody {
      background-color: #FFFFFF;

      tr {
        td {
          padding: 12px;
          border-right: 1px solid #dcdfe6;
          border-bottom: 1px solid #dcdfe6;
        }
      }
    }
  }

  .work-collection-table {
    table {
      width: 100%;
      border-left: 1px solid #dcdfe6;
      border-top: 1px solid #dcdfe6;

      thead {
        background-color: #FFFFFF;
        font-size: 14px;

        tr {
          th {
            padding: 12px 0;
            border-right: 1px solid #dcdfe6;
            border-bottom: 1px solid #dcdfe6;
            background-color: #dcdfe6;
            color: #333;
          }
        }
      }

      tbody {
        background-color: #FFFFFF;

        tr {
          td {
            padding: 12px;
            border-right: 1px solid #dcdfe6;
            border-bottom: 1px solid #dcdfe6;
          }
        }
      }
    }
  }

  .chart-container {
    background-size: 100% 100%;
  }

  .op-box {
    background-color: #6a6a6a;
    display: flex;
    align-items: center;
    justify-content: space-around;

    .op-bar-btn {
      width: 60px;
      height: 60px;
      position: absolute;
      left: 50%;
      top: 50%;
      transform: translate(-50%, -50%);
      background-size: 100% 100%;
      cursor: pointer;
      transform-origin: 50% 50%;
    }

    .op-bar-label {
      color: #fff;
      position: absolute;
      font-size: 11px;
    }

    .op-bar-label1 {
      right: 20px;
      top: 20px;
    }

    .op-bar-label2 {
      top: 50%;
      right: 0;
      transform: translateY(-50%);
    }

    .op-bar-label3 {
      top: 70%;
      right: 0;
    }

    .op-bar-label4 {
      bottom: 12px;
      left: 50%;
      transform: translateX(-50%);
    }

    .op-bar-label5 {
      top: 70%;
      left: 8px;
    }

    .op-bar-label6 {
      top: 50%;
      left: 0;
      transform: translateY(-50%);
    }

    .op-bar-label7 {
      top: 20px;
      left: 12px;
    }

    .op-bar-label8 {
      left: 50%;
      top: 8px;
      transform: translateX(-50%);
    }

    .op-bar2-label1 {
      right: 20px;
      top: 20px;
    }

    .op-bar2-label2 {
      top: 50%;
      right: 12px;
      transform: translateY(-50%);
    }

    .op-bar2-label3 {
      top: 70%;
      right: 20px;
    }

    .op-bar2-label4 {
      bottom: 12px;
      left: 50%;
      transform: translateX(-50%);
    }

    .op-bar2-label5 {
      top: 70%;
      left: 12px;
    }

    .op-bar2-label6 {
      top: 50%;
      left: 0;
      transform: translateY(-50%);
    }

    .op-bar2-label7 {
      top: 20px;
      left: 12px;
    }

    .op-bar1,
    .op-bar2,
    .op-bar3 {
      height: 120px;
      width: 120px;
      position: relative;
    }
  }

  .single-bound {
    width: 240px;
    height: 256px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
    background-color: #eee;
    position: relative;
    //background-image: url('@/assets/images/preview-device.jpg');
    background-size: 100% 120px;
    background-repeat: no-repeat;
    box-sizing: border-box;
    border-radius: 8px 8px 0 0;
    border-top: 12px solid #504d4d;
    border-left: 12px solid #504d4d;
    border-right: 12px solid #504d4d;
    z-index: 10;

    .single-bound--title {
      position: absolute;
      left: 34px;
      top: 10px;
      font-size: 16px;
      color: #333333;
      user-select: none;
      z-index: 200;
    }

    .single-bound--unit {
      position: absolute;
      right: 44px;
      bottom: 160px;
      font-size: 16px;
      font-weight: 600;
      color: #333333;
    }

    .single-bound--btn-bound {
      position: absolute;
      bottom: 0;
      z-index: 100;
      width: 100%;
      height: 136px;
      background-repeat: no-repeat;
      background-position: center center;
      background-color: #504d4d;

      .single-bound--btn {
        width: 100px;
        height: 100px;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        background-size: 100% 100%;
        cursor: pointer;
        transform-origin: 50% 50%;
      }

      .single-bound--control-label {
        position: absolute;
        color: #f0f0f0;

        &.label1 {
          left: 144px;
          top: 12px;
        }

        &.label2 {
          left: 166px;
          top: 50%;
        }

        &.label3 {
          bottom: 0;
          left: 53%;
        }

        &.label4 {
          left: 28%;
          bottom: 10%;
        }

        &.label5 {
          left: 20%;
          top: 32%;
        }

        &.label6 {
          left: 38%;
          top: 3%;
        }
      }
    }

    .single-bound--value {
      position: absolute;
      font-size: 30px;
      font-weight: 600;
      bottom: calc(22px + 136px);
      left: 40px;
      color: #333333;
    }
  }

  p > select {
    width: 250px;
    padding: 10px 35px 10px 15px;
    font-size: 16px;
    color: #333;
    background-color: white;
    border: 1px solid #ddd;
    border-radius: 6px;
    appearance: none;
    -webkit-appearance: none;
    -moz-appearance: none;
    background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e");
    background-repeat: no-repeat;
    background-position: right 10px center;
    background-size: 16px;
    cursor: pointer;
    box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    transition: all 0.2s ease;

    &:hover {
      border-color: #bbb;
    }

    &:focus {
      outline: none;
      border-color: #4a90e2;
      box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
    }

    option {
      padding: 8px;
    }
  }

  p label {
    display: flex;
    align-items: center;
    width: 250px;
    height: 42px; /* 与select高度匹配 */
    cursor: pointer;
    position: relative;
    font-size: 16px;
    color: #333;
    padding-left: 35px;

    &:before {
      content: "";
      position: absolute;
      left: 0;
      top: 50%;
      transform: translateY(-50%);
      width: 20px;
      height: 20px;
      background: white;
      border: 1px solid #ddd;
      border-radius: 4px;
      transition: all 0.2s ease;
      box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }

    &:hover:before {
      border-color: #bbb;
    }
  }

  p input[type=checkbox] {
    position: absolute;
    opacity: 0;
    height: 0;
    width: 0;

    &:checked + label:before {
      background-color: #4a90e2;
      border-color: #4a90e2;
    }

    &:checked + label:after {
      content: "";
      position: absolute;
      left: 7px;
      top: 50%;
      transform: translateY(-50%) rotate(45deg);
      width: 5px;
      height: 10px;
      border: solid white;
      border-width: 0 2px 2px 0;
    }

    &:focus + label:before {
      border-color: #4a90e2;
      box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
    }

    &:disabled + label {
      color: #aaa;
      cursor: not-allowed;
    }

    &:disabled + label:before {
      background: #f0f0f0;
      border-color: #ddd;
    }
  }

  p.custom-answer[contenteditable="true"] {
    width: 100%;
    min-height: 120px;
    padding: 12px 15px;
    font-size: 16px;
    line-height: 1.5;
    color: #333;
    background-color: white;
    border: 1px solid #ddd;
    border-radius: 8px;
    outline: none;
    box-shadow: 0 2px 5px rgba(0,0,0,0.1);
    transition: all 0.3s ease;
    overflow-y: auto;

    &:focus {
      border-color: #4a90e2;
      box-shadow: 0 0 0 3px rgba(74, 144, 226, 0.2);
    }

    &:empty:before {
      content: attr(placeholder);
      color: #aaa;
      pointer-events: none;
      display: block;
    }
  }
}
</style>
